package com.atguigu.userservice.controller;

import com.atguigu.commonutils.JwtUtils;
import com.atguigu.servicebase.exceptionhandler.GuliException;
import com.atguigu.userservice.entity.UcenterMember;
import com.atguigu.userservice.service.UcenterMemberService;
import com.atguigu.userservice.utils.ConstantWxUtils;
import com.atguigu.userservice.utils.HttpClientUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.Gson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Member;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.UUID;

@Api(description = "微信登录注册")
//原来需要在Controller上面加上@CrossOrigin解决跨域问题，现在gateway已经处理了
//@RestController //这里没有配置@RestController
@Controller    /*注意这里是return的一个地址，并不需要返回json数据*/
@RequestMapping("/api/ucenter/wx")
public class WxApiController {

    @Autowired
    private UcenterMemberService memberService;

    @ApiOperation(value = "生成微信扫描的二维码")
    @GetMapping("login")
    public String genQrConnect(HttpSession session){
        /*1.微信开发平台授权baseUrl*/
        String baseUrl= "https://open.weixin.qq.com/connect/qrconnect"+
                "?appid=%s" +
                "&redirect_uri=%s" +
                "&response_type=code" +
                "&scope=snsapi_login" +
                "&state=%s" +
                "#wechat_redirect";

        /*2.回调地址*//*获取业务服务器重定向地址*/
        String redirectUrl=ConstantWxUtils.WX_OPEN_REDIRECT_URL;
        try {
            redirectUrl = URLEncoder.encode(redirectUrl, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new GuliException(20001,e.getMessage());
        }

        /*3.防止csrf攻击，(跨站请求伪造攻击)*/
//        String state= UUID.randomUUID().toString().replaceAll("-", "");
        String state="imhelen";//为了让大家能够使用我搭建的外网的微信回调跳转服务器，这里填写你在ngrok的前置域名
        System.out.println("state="+state);

        /*4.采用redis等进行缓存state，使用sessionId为key，30分钟后过期可以配置*/
        //键："wechar-open-state-" + httpServletRequest.getSession().getId()
        //值：satte
        /*过期时间：30分钟*/

        /*5.生成qrcodeUrl*/
        String qrcodeUrl = String.format(baseUrl,
                ConstantWxUtils.WX_OPEN_APP_ID,
                redirectUrl,
                state);
        return "redirect:"+qrcodeUrl;

    }

    /*扫码之后，就会调用这个方法，从code和state里面得到扫码人的信息*/
    @ApiOperation(value = "获取扫描人信息，添加数据")
    @GetMapping("/callback")
    public String callback(String code,String state){
        /*1.得到临时授权票据：code and state*/
        System.out.println("code:"+code+",state:"+state);

        /*2.从redis里面将之前存入的state取出来，和当前传入的state作比较，如果一致则放行，如果不一致，就抛出异常，非法访问*/

        /*3.向认证服务器发送请求，获得accessToken*/
        String baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" +
                "?appid=%s" +
                "&secret=%s" +
                "&code=%s" +
                "&grant_type=authorization_code";
        String accessTokenUrl = String.format(baseAccessTokenUrl,
                ConstantWxUtils.WX_OPEN_APP_ID,
                ConstantWxUtils.WX_OPEN_APP_SECRET,
                code);
        String accessToken=null;
        try {
            accessToken = HttpClientUtils.get(accessTokenUrl);
            System.out.println("获取到的accessToken是："+accessToken);
        } catch (Exception e) {
            throw new GuliException(20001,"获取accessToken失败~");
        }

        /*4.将获取到的accessToken字符串使用json工具转换为hashmap的形式，方便我们获取里面的数据*/
        Gson gson = new Gson();
        HashMap hashMap = gson.fromJson(accessToken, HashMap.class);
        String access_token = (String) hashMap.get("access_token");
        String openid = (String) hashMap.get("openid");

        /*5.根据openid去查询数据库，查看当前用户原来是否注册过，没有注册过的话，就进一步根据openid获取用户信息*/
        QueryWrapper<UcenterMember> wrapper = new QueryWrapper<>();
        wrapper.eq("openid", openid);
        UcenterMember user = memberService.getOne(wrapper);
        UcenterMember member = null;
        if(StringUtils.isEmpty(user)){
            /*该用户原来没有注册过，根据openid获取用户信息，添加到数据库里面*/
            /*访问微信的资源服务器，获取用户信息*/
            String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                    "?access_token=%s" +
                    "&openid=%s";
            String userInfoUrl = String.format(baseUserInfoUrl, access_token, openid);
            String resultUserInfo = null;
            try {
                resultUserInfo = HttpClientUtils.get(userInfoUrl);
                System.out.println("获取到的用户信息是：" + resultUserInfo);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //解析json
            HashMap<String, Object> mapUserInfo = gson.fromJson(resultUserInfo, HashMap.class);
            System.out.println("用户信息："+mapUserInfo);
            String nickname = (String)mapUserInfo.get("nickname");
            String headimgurl = (String)mapUserInfo.get("headimgurl");
            /*向数据库插入注册用户信息*/
            member = new UcenterMember();
            member.setAvatar(headimgurl);
            member.setNickname(nickname);
            member.setOpenid(openid);
            memberService.save(member);
        }
        /*使用jwt根据member对象，生成token字符串*/
        String jwtToken = JwtUtils.getJwtToken(user.getId(), user.getNickname());
        System.out.println("生成的token:"+jwtToken);
        /*表示数据库里面有这个数据，所以登陆成功，返回首页，通过路径的方式，传递token字符串给首页*/
        return "redirect:http://localhost:3000?token="+jwtToken;/*这样传递的方式就解决了跨域问题*/
    }


}